{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Systemd"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Systemdとは\n",
    "\n",
    "* Linuxの起動処理やシステム管理を行う仕組み\n",
    "* Linuxの起動処理4段階の中での位置づけ\n",
    "    1. 電源投入によりBIOSが起動する\n",
    "    1. BIOSからブートローダーが呼び出される\n",
    "    1. ブートローダーがLinuxカーネルを起動する\n",
    "    1. Linuxカーネルがinitプロセス(PID 1)を起動する\n",
    "        * initプロセス\n",
    "            * Sysvinit : Linuxで古くから使われていた\n",
    "            * Upstart : Ununtuで一時使われていた\n",
    "            * <font color=\"red\">Systemd</font> : 現在多くのLinuxでデフォルトinitシステムとして採用されている\n",
    "* 特徴\n",
    "    * シェルスクリプトではない\n",
    "        * <font color=\"red\">サービスを「Unit」という単位で管理</font>し、設定ファイルとして持つ\n",
    "            * 処理を細分化でき個別に実効することが可能\n",
    "        * 処理ごとの依存関係を明確にすることが出来る\n",
    "        * 並列での実行も可能\n",
    "            * Aの処理の後にBとCを並列実行するなど\n",
    "    * プロセス起動が柔軟\n",
    "        * 様々なトリガーを契機にプロセスの起動が可能\n",
    "            * タイマー\n",
    "            * ソケット通信検出\n",
    "            * ファイルシステムのマウント\n",
    "            * etc...\n",
    "    * PIDではなくcgroupによってプロセスを管理する\n",
    "        * SysvinitではサービスをPIDによって管理していた\n",
    "            * プロセスが2回forkすると親プロセスと孫プロセスの直接的な関係性は切れる\n",
    "            * cgroupの場合は複数回forkが発生しても管理下における\n",
    "        * cgroupはLinux以外では使えない\n",
    "            * Linuxカーネルの機能であるため"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Unitタイプ\n",
    "\n",
    "* .service\n",
    "    * 指定のバイナリを実行する\n",
    "* .socket\n",
    "    * systemdがSocketをListenして、接続があるとプロセスに受け渡す\n",
    "    * xinetdの代替的な機能\n",
    "* .target \n",
    "    * 複数のユニットをまとめるために使用する\n",
    "* .device \n",
    "    * udevから通知されたデバイスを表す\n",
    "* .snapshot \n",
    "    * ある時点のユニットの状態\n",
    "* .path \n",
    "    * 指定のファイルが生成されると指定されたサービスを起動する\n",
    "* .mount\n",
    "    * 指定のファイルシステムをマウントする\n",
    "* .automount \n",
    "    * オートマウント処理を実施する\n",
    "    * automountdの代替的な機能"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 動作モード\n",
    "\n",
    "* initの欄レベルに相当する\n",
    "* Unixタイプの「target」で表す\n",
    "* systemctlのisolateコマンドで切り替える\n",
    "    * 「rescue.target」「emergency.target」はisolateをつけずにモードを切り替えるとログインしているユーザにメッセージを送信する\n",
    "    * それ以外の動作はほぼ同じ\n",
    "* ターゲットと動作モード\n",
    "    * rescue.target : レスキューモード\n",
    "        * どうしても終了しないプロセスがあるなどの状況でシステムを修復する場合に使う\n",
    "        * シングルユーザーモード(init 1)とほぼ同等\n",
    "            * システムによってはネットワークシステムを使う・使わないなどの違いがある\n",
    "    * emergency.target : 緊急モード\n",
    "        * レスキューモードでも入れない場合に使う\n",
    "    * multi-user.target : CUIモード\n",
    "    * graphical.target : GUIモード\n",
    "    \n",
    "コマンド例\n",
    "\n",
    "```\n",
    "### GUIモードにする\n",
    "$ sudo systemctl isolate graphical.target\n",
    "\n",
    "### デフォルト(起動時)のモードにする\n",
    "$ sudo systemctl default\n",
    "\n",
    "### レスキューモードにする\n",
    "$ sudo systemctl rescue\n",
    "もしくは\n",
    "$ sudo systemctl isolate rescue.target\n",
    "\n",
    "### 緊急モードにする\n",
    "$ sudo systemctl emergency\n",
    "もしくは\n",
    "$ sudo systemctl isolate emergency.target\n",
    "\n",
    "### デフォルトをGUIモードにする\n",
    "$ sudo systemctl set-default graphical.target\n",
    "\n",
    "### initのランレベル(ここではランレベル3)での指定も可能\n",
    "$ systemctl isolate runlevel3.target\n",
    "\n",
    "### 対応\n",
    "$ ls -l /usr/lib/systemd/system/runlevel*.target\n",
    "================================================\n",
    "lrwxrwxrwx 1 root root 15  4月 21 13:47 /usr/lib/systemd/system/runlevel0.target -> poweroff.target\n",
    "lrwxrwxrwx 1 root root 13  4月 21 13:47 /usr/lib/systemd/system/runlevel1.target -> rescue.target\n",
    "lrwxrwxrwx 1 root root 17  4月 21 13:47 /usr/lib/systemd/system/runlevel2.target -> multi-user.target\n",
    "lrwxrwxrwx 1 root root 17  4月 21 13:47 /usr/lib/systemd/system/runlevel3.target -> multi-user.target\n",
    "lrwxrwxrwx 1 root root 17  4月 21 13:47 /usr/lib/systemd/system/runlevel4.target -> multi-user.target\n",
    "lrwxrwxrwx 1 root root 16  4月 21 13:47 /usr/lib/systemd/system/runlevel5.target -> graphical.target\n",
    "lrwxrwxrwx 1 root root 13  4月 21 13:47 /usr/lib/systemd/system/runlevel6.target -> reboot.target\n",
    "================================================\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### @つきサービス\n",
    "\n",
    "* 複数インスタンスを作成するときに使うテンプレート\n",
    "* tomcatの例\n",
    "    * 別ポートでもう1個tomcatを立ち上げたい時\n",
    "        1. /etc/systemd/system にtomcat@.service を複製\n",
    "        1. systemctl daemon-reloadを実行\n",
    "        1. systemctl enable tomcat@inst2.serviceを実行\n",
    "            * 別インスタンスの設定ができる\n",
    "        1. /var/lib/tomcats/inst2 に別インスタンスの環境を作る\n",
    "        1. systemctl start tomcat@inst2.service で起動する\n",
    "    * tomcatは「tomcat.service」も「tomcat@.service」も中身はほぼ同じ"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## サービス管理"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 有効化されているUnitの一覧表示(list-units)\n",
    "\n",
    "```\n",
    "### 表示例\n",
    "$ systemctl list-units\n",
    "================================================\n",
    "UNIT         LOAD    ACTIVE SUB       DESCRIPTION\n",
    "...\n",
    "sshd.service loaded  active running   OpenSSH server daemon\n",
    "...\n",
    "================================================\n",
    "```"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  UNIT                                              LOAD   ACTIVE SUB       \n",
      "  proc-sys-fs-binfmt_misc.automount                 loaded active running   Arbitrary Executable File Formats File System Automount Point\n",
      "  sys-devices-pci0000:00-0000:00:07.1-ata2-host2-target2:0:0-2:0:0:0-block-sr0.device                  loaded active plugged   VMware_Virtual_IDE_CDROM_Drive\n",
      "  sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda-sda1.device     loaded active plugged   Virtual_disk 1\n",
      "  sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda-sda2.device     loaded active plugged   LVM PV KNtUzQ-9EEr-26Qy-883S-TNeX-T1f5-b9Gw8F on /dev/sda2 2\n",
      "  sys-devices-pci0000:00-0000:00:15.0-0000:03:00.0-host0-target0:0:0-0:0:0:0-block-sda.device          loaded active plugged   Virtual_disk\n",
      "  sys-devices-pci0000:00-0000:00:16.0-0000:0b:00.0-net-eno16780032.device                              loaded active plugged   VMXNET3 Ethernet Controller\n",
      "  sys-devices-platform-serial8250-tty-ttyS0.device  loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS0\n",
      "  sys-devices-platform-serial8250-tty-ttyS1.device  loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS1\n",
      "  sys-devices-platform-serial8250-tty-ttyS2.device  loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS2\n",
      "  sys-devices-platform-serial8250-tty-ttyS3.device  loaded active plugged   /sys/devices/platform/serial8250/tty/ttyS3\n",
      "  sys-devices-virtual-block-dm\\x2d0.device          loaded active plugged   /sys/devices/virtual/block/dm-0\n",
      "  sys-devices-virtual-block-dm\\x2d1.device          loaded active plugged   /sys/devices/virtual/block/dm-1\n",
      "  sys-devices-virtual-net-docker0.device            loaded active plugged   /sys/devices/virtual/net/docker0\n",
      "  sys-devices-virtual-net-veth7319eab.device        loaded active plugged   /sys/devices/virtual/net/veth7319eab\n",
      "  sys-devices-virtual-net-veth89b7901.device        loaded active plugged   /sys/devices/virtual/net/veth89b7901\n",
      "  sys-devices-virtual-net-vethb8f0373.device        loaded active plugged   /sys/devices/virtual/net/vethb8f0373\n",
      "  sys-devices-virtual-net-vethfb56052.device        loaded active plugged   /sys/devices/virtual/net/vethfb56052\n",
      "  sys-module-configfs.device                        loaded active plugged   /sys/module/configfs\n",
      "  sys-subsystem-net-devices-docker0.device          loaded active plugged   /sys/subsystem/net/devices/docker0\n",
      "  sys-subsystem-net-devices-eno16780032.device      loaded active plugged   VMXNET3 Ethernet Controller\n",
      "  sys-subsystem-net-devices-veth7319eab.device      loaded active plugged   /sys/subsystem/net/devices/veth7319eab\n",
      "  sys-subsystem-net-devices-veth89b7901.device      loaded active plugged   /sys/subsystem/net/devices/veth89b7901\n",
      "  sys-subsystem-net-devices-vethb8f0373.device      loaded active plugged   /sys/subsystem/net/devices/vethb8f0373\n",
      "  sys-subsystem-net-devices-vethfb56052.device      loaded active plugged   /sys/subsystem/net/devices/vethfb56052\n",
      "  -.mount                                           loaded active mounted   /\n",
      "  boot.mount                                        loaded active mounted   /boot\n",
      "  dev-hugepages.mount                               loaded active mounted   Huge Pages File System\n",
      "  dev-mqueue.mount                                  loaded active mounted   POSIX Message Queue File System\n",
      "  proc-sys-fs-binfmt_misc.mount                     loaded active mounted   Arbitrary Executable File Formats File System\n",
      "  run-docker-netns-2e781ab636ba.mount               loaded active mounted   /run/docker/netns/2e781ab636ba\n",
      "  run-docker-netns-3114360fe723.mount               loaded active mounted   /run/docker/netns/3114360fe723\n",
      "  run-docker-netns-c9e675601c81.mount               loaded active mounted   /run/docker/netns/c9e675601c81\n",
      "  run-docker-netns-d37f347083a2.mount               loaded active mounted   /run/docker/netns/d37f347083a2\n",
      "  run-user-1000.mount                               loaded active mounted   /run/user/1000\n",
      "  sys-kernel-config.mount                           loaded active mounted   Configuration File System\n",
      "  sys-kernel-debug.mount                            loaded active mounted   Debug File System\n",
      "  var-lib-docker-containers-01faf6b40cba91744d1577ec7a28260dd7ee641b68d03e1d29b663a5e5a34b7e-shm.mount loaded active mounted   /var/lib/docker/containers/01faf6b40cba91744d1577ec7a28260dd7ee641b68d03e1d29b663a5e5a34b7e/shm\n",
      "  var-lib-docker-containers-49914008c382cc73ae56fae7cb2f4a572d5ea046ebe1475b7a02845c7458ca3e-shm.mount loaded active mounted   /var/lib/docker/containers/49914008c382cc73ae56fae7cb2f4a572d5ea046ebe1475b7a02845c7458ca3e/shm\n",
      "  var-lib-docker-containers-c91b49b1012fef449ba6aed28ad1580e0edd48afc54b5668f1bf46ca0995381d-shm.mount loaded active mounted   /var/lib/docker/containers/c91b49b1012fef449ba6aed28ad1580e0edd48afc54b5668f1bf46ca0995381d/shm\n",
      "  var-lib-docker-containers-d8eb45ab72c7b7473a9cfb212f5b77405ef89680f1c52b2f6ca1a7a1b6fb681b-shm.mount loaded active mounted   /var/lib/docker/containers/d8eb45ab72c7b7473a9cfb212f5b77405ef89680f1c52b2f6ca1a7a1b6fb681b/shm\n",
      "  var-lib-docker-overlay-592c41e62762f1d112ba1530f33efb2e93944e563610e8bf1eff98d5942ca389-merged.mount loaded active mounted   /var/lib/docker/overlay/592c41e62762f1d112ba1530f33efb2e93944e563610e8bf1eff98d5942ca389/merged\n",
      "  var-lib-docker-overlay-6ddadf89531d056efd5cdd3bcb5702ce6234affa69c213bab6eae514c5f88013-merged.mount loaded active mounted   /var/lib/docker/overlay/6ddadf89531d056efd5cdd3bcb5702ce6234affa69c213bab6eae514c5f88013/merged\n",
      "  var-lib-docker-overlay-8bbdff1ec30bc54e46ba177c1ae653e0edcd35b5340f3647e2af5c167977c9fc-merged.mount loaded active mounted   /var/lib/docker/overlay/8bbdff1ec30bc54e46ba177c1ae653e0edcd35b5340f3647e2af5c167977c9fc/merged\n",
      "  var-lib-docker-overlay-c9388cd357cad3775b024fcb29ca301bae7e173f6f910cac12d3f58a473f05ee-merged.mount loaded active mounted   /var/lib/docker/overlay/c9388cd357cad3775b024fcb29ca301bae7e173f6f910cac12d3f58a473f05ee/merged\n",
      "  var-lib-docker-overlay.mount                      loaded active mounted   /var/lib/docker/overlay\n",
      "  brandbot.path                                     loaded active waiting   Flexible branding\n",
      "  systemd-ask-password-plymouth.path                loaded active waiting   Forward Password Requests to Plymouth Directory Watch\n",
      "  systemd-ask-password-wall.path                    loaded active waiting   Forward Password Requests to Wall Directory Watch\n",
      "  session-8401.scope                                loaded active abandoned Session 8401 of user jsd\n",
      "  auditd.service                                    loaded active running   Security Auditing Service\n",
      "  chronyd.service                                   loaded active running   NTP client/server\n",
      "  crond.service                                     loaded active running   Command Scheduler\n",
      "  dbus.service                                      loaded active running   D-Bus System Message Bus\n",
      "  docker.service                                    loaded active running   Docker Application Container Engine\n",
      "● getty@tty1.service                                loaded failed failed    Getty on tty1\n",
      "  irqbalance.service                                loaded active running   irqbalance daemon\n",
      "  jexec.service                                     loaded active exited    LSB: Supports the direct execution of binary formats.\n",
      "  kmod-static-nodes.service                         loaded active exited    Create list of required static device nodes for the current kernel\n",
      "  lvm2-lvmetad.service                              loaded active running   LVM2 metadata daemon\n",
      "  lvm2-monitor.service                              loaded active exited    Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling\n",
      "  lvm2-pvscan@8:2.service                           loaded active exited    LVM2 PV scan on device 8:2\n",
      "  network.service                                   loaded active exited    LSB: Bring up/down networking\n",
      "  NetworkManager-wait-online.service                loaded active exited    Network Manager Wait Online\n",
      "  NetworkManager.service                            loaded active running   Network Manager\n",
      "  polkit.service                                    loaded active running   Authorization Manager\n",
      "  postfix.service                                   loaded active running   Postfix Mail Transport Agent\n",
      "  rhel-dmesg.service                                loaded active exited    Dump dmesg to /var/log/dmesg\n",
      "  rhel-import-state.service                         loaded active exited    Import network configuration from initramfs\n",
      "  rhel-readonly.service                             loaded active exited    Configure read-only root support\n",
      "  rsyslog.service                                   loaded active running   System Logging Service\n",
      "  sshd.service                                      loaded active running   OpenSSH server daemon\n",
      "  sysstat.service                                   loaded active exited    Resets System Activity Logs\n",
      "  systemd-journal-flush.service                     loaded active exited    Flush Journal to Persistent Storage\n",
      "  systemd-journald.service                          loaded active running   Journal Service\n",
      "  systemd-logind.service                            loaded active running   Login Service\n",
      "  systemd-random-seed.service                       loaded active exited    Load/Save Random Seed\n",
      "  systemd-remount-fs.service                        loaded active exited    Remount Root and Kernel File Systems\n",
      "  systemd-sysctl.service                            loaded active exited    Apply Kernel Variables\n",
      "  systemd-tmpfiles-setup-dev.service                loaded active exited    Create Static Device Nodes in /dev\n",
      "  systemd-tmpfiles-setup.service                    loaded active exited    Create Volatile Files and Directories\n",
      "  systemd-udev-trigger.service                      loaded active exited    udev Coldplug all Devices\n",
      "  systemd-udevd.service                             loaded active running   udev Kernel Device Manager\n",
      "  systemd-update-utmp.service                       loaded active exited    Update UTMP about System Boot/Shutdown\n",
      "  systemd-user-sessions.service                     loaded active exited    Permit User Sessions\n",
      "  systemd-vconsole-setup.service                    loaded active exited    Setup Virtual Console\n",
      "  tuned.service                                     loaded active running   Dynamic System Tuning Daemon\n",
      "  vmtoolsd.service                                  loaded active running   Service for virtual machines hosted on VMware\n",
      "  yum-cron.service                                  loaded active exited    Run automatic yum updates as a cron job\n",
      "  -.slice                                           loaded active active    Root Slice\n",
      "  system-getty.slice                                loaded active active    system-getty.slice\n",
      "  system-lvm2\\x2dpvscan.slice                       loaded active active    system-lvm2\\x2dpvscan.slice\n",
      "  system-selinux\\x2dpolicy\\x2dmigrate\\x2dlocal\\x2dchanges.slice                                        loaded active active    system-selinux\\x2dpolicy\\x2dmigrate\\x2dlocal\\x2dchanges.slice\n",
      "  system.slice                                      loaded active active    System Slice\n",
      "  user-1000.slice                                   loaded active active    user-1000.slice\n",
      "  user.slice                                        loaded active active    User and Session Slice\n",
      "  dbus.socket                                       loaded active running   D-Bus System Message Bus Socket\n",
      "  dm-event.socket                                   loaded active listening Device-mapper event daemon FIFOs\n",
      "  lvm2-lvmetad.socket                               loaded active running   LVM2 metadata daemon socket\n",
      "  lvm2-lvmpolld.socket                              loaded active listening LVM2 poll daemon socket\n",
      "  systemd-initctl.socket                            loaded active listening /dev/initctl Compatibility Named Pipe\n",
      "  systemd-journald.socket                           loaded active running   Journal Socket\n",
      "  systemd-shutdownd.socket                          loaded active listening Delayed Shutdown Socket\n",
      "  systemd-udevd-control.socket                      loaded active running   udev Control Socket\n",
      "  systemd-udevd-kernel.socket                       loaded active running   udev Kernel Socket\n",
      "  dev-mapper-centos\\x2dswap.swap                    loaded active active    /dev/mapper/centos-swap\n",
      "  basic.target                                      loaded active active    Basic System\n",
      "  cryptsetup.target                                 loaded active active    Encrypted Volumes\n",
      "  getty.target                                      loaded active active    Login Prompts\n",
      "  local-fs-pre.target                               loaded active active    Local File Systems (Pre)\n",
      "  local-fs.target                                   loaded active active    Local File Systems\n",
      "  multi-user.target                                 loaded active active    Multi-User System\n",
      "  network-online.target                             loaded active active    Network is Online\n",
      "  network.target                                    loaded active active    Network\n",
      "  paths.target                                      loaded active active    Paths\n",
      "  remote-fs.target                                  loaded active active    Remote File Systems\n",
      "  slices.target                                     loaded active active    Slices\n",
      "  sockets.target                                    loaded active active    Sockets\n",
      "  swap.target                                       loaded active active    Swap\n",
      "  sysinit.target                                    loaded active active    System Initialization\n",
      "  timers.target                                     loaded active active    Timers\n",
      "  systemd-tmpfiles-clean.timer                      loaded active waiting   Daily Cleanup of Temporary Directories\n",
      "\n",
      "LOAD   = Reflects whether the unit definition was properly loaded.\n",
      "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n",
      "SUB    = The low-level unit activation state, values depend on unit type.\n",
      "\n",
      "121 loaded units listed. Pass --all to see loaded but inactive units, too.\n",
      "To show all installed unit files use 'systemctl list-unit-files'.\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "systemctl list-units --no-pager | sed -e 's/                                                   //'"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### インストールされているUnitファイルの一覧表示(list-unit-files)\n",
    "\n",
    "```\n",
    "### 表示例\n",
    "$ systemctl list-unit-files --no-pager | grep sshd\n",
    "================================================\n",
    "UNIT FILE                                     STATE\n",
    "...\n",
    "sshd-keygen.service                           static\n",
    "sshd.service                                  enabled\n",
    "sshd@.service                                 static\n",
    "sshd.socket                                   disabled\n",
    "================================================\n",
    "\n",
    "### serviceのみ表示する場合は -t serviceオプションをつける\n",
    "$ systemctl list-unit-files -t service --no-pager | grep sshd\n",
    "================================================\n",
    "UNIT FILE                                     STATE\n",
    "...\n",
    "sshd-keygen.service                           static\n",
    "sshd.service                                  enabled\n",
    "sshd@.service                                 static\n",
    "================================================\n",
    "```\n",
    "\n",
    "* STATE\n",
    "    * enabled\n",
    "        * 有効になっている\n",
    "    * disabled\n",
    "        * 無効になっている\n",
    "    * static\n",
    "        * 有効化／無効化の対象外\n",
    "            * UnitファイルにWantedBy句がそもそも指定されていない\n",
    "        * 他のユニットに依存するもの\n",
    "            * これ単体で有効/無効が設定できない\n",
    "\n",
    "* Unitファイルの実態\n",
    "    * /usr/lib/systemd/system\n",
    "        * RPMから直接ファイルが提供される場所\n",
    "        * システムのデフォルト設定\n",
    "        * <font color=\"red\">ここのファイルは基本的に直接編集するべきではない</font>\n",
    "            * カスタマイズは /etc/systemd/system にコピーして実施\n",
    "    * /etc/systemd/system \n",
    "        * ここに同名のファイルを配置するとデフォルト設定より優先される\n",
    "    * /etc/systemd/system/(サービス名).service.d/(任意の名前).conf\n",
    "        * システムデフォルト設定で、設定を追加または修正する場合\n",
    "            * /usr/lib/systemd/system 配下のファイルは直接編集しないため\n",
    "\n",
    "```\n",
    "### /etc/systemd/system/httpd.service.d/privatetmp.conf\n",
    "================================================\n",
    "[Service]\n",
    "PrivateTmp=false\n",
    "================================================\n",
    "\n",
    "※ これで /usr/lib/systemd/system/httpd.service で「PrivateTmp=true」となっていても設定は「PrivateTmp=false」となる\n",
    "```\n",
    "    \n",
    "    \n",
    "    "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 26,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "### sshdのシステムのデフォルト設定\n",
      "$ ls -lh /usr/lib/systemd/system/*sshd*\n",
      "================================================\n",
      "-rw-r--r--. 1 root root 313  4月 12 23:05 /usr/lib/systemd/system/sshd-keygen.service\n",
      "-rw-r--r--. 1 root root 402  4月 12 23:05 /usr/lib/systemd/system/sshd.service\n",
      "-rw-r--r--. 1 root root 181  4月 12 23:05 /usr/lib/systemd/system/sshd.socket\n",
      "-rw-r--r--. 1 root root 260  4月 12 23:05 /usr/lib/systemd/system/sshd@.service\n",
      "================================================\n",
      "\n",
      "### /etc/systemd/system 配下\n",
      "$ ls -lh /etc/systemd/system | sed -e \"s/-> /\\n-> /\"\n",
      "================================================\n",
      "合計 4.0K\n",
      "drwxr-xr-x. 2 root root   30  7月  3 14:27 basic.target.wants\n",
      "lrwxrwxrwx. 1 root root   46  7月  3 14:16 dbus-org.freedesktop.NetworkManager.service \n",
      "  -> /usr/lib/systemd/system/NetworkManager.service\n",
      "lrwxrwxrwx. 1 root root   57  7月  3 14:16 dbus-org.freedesktop.nm-dispatcher.service \n",
      "  -> /usr/lib/systemd/system/NetworkManager-dispatcher.service\n",
      "lrwxrwxrwx. 1 root root   37  7月  3 14:18 default.target \n",
      "  -> /lib/systemd/system/multi-user.target\n",
      "drwxr-xr-x. 2 root root   85  7月  3 14:16 default.target.wants\n",
      "drwxr-xr-x. 2 root root   31  7月  3 14:16 getty.target.wants\n",
      "drwxr-xr-x. 2 root root 4.0K  7月 14 09:33 multi-user.target.wants\n",
      "drwxr-xr-x. 2 root root   28  7月  3 14:16 sockets.target.wants\n",
      "drwxr-xr-x. 2 root root   86  7月  3 14:16 sysinit.target.wants\n",
      "drwxr-xr-x. 2 root root   43  7月  3 14:16 system-update.target.wants\n",
      "================================================\n",
      "\n",
      "### /etc/systemd/system/multi-user.target.wants 配下にsshd.serviceのsymlink\n",
      "$ ls -lh /etc/systemd/system/multi-user.target.wants/sshd.service | sed -e \"s/-> /\\n-> /\"\n",
      "================================================\n",
      "lrwxrwxrwx. 1 root root 36  7月  3 14:16 /etc/systemd/system/multi-user.target.wants/sshd.service \n",
      "  -> /usr/lib/systemd/system/sshd.service\n",
      "================================================\n",
      "\n",
      "### multi-user.targetは有効になっている\n",
      "$ systemctl list-unit-files --no-pager | grep multi-user.target\n",
      "================================================\n",
      "multi-user.target                             enabled \n",
      "================================================\n",
      "※ つまり、CUIモードではsshd.serviceが起動する\n"
     ]
    }
   ],
   "source": [
    "%%bash\n",
    "\n",
    "echo \"### sshdのシステムのデフォルト設定\"\n",
    "echo '$ ls -lh /usr/lib/systemd/system/*sshd*'\n",
    "echo \"================================================\"\n",
    "ls -lh /usr/lib/systemd/system/*sshd*\n",
    "echo \"================================================\"\n",
    "echo \"\"\n",
    "\n",
    "echo \"### /etc/systemd/system 配下\"\n",
    "echo '$ ls -lh /etc/systemd/system | sed -e \"s/-> /\\n-> /\"'\n",
    "echo \"================================================\"\n",
    "ls -lh /etc/systemd/system | sed -e \"s/-> /\\n  -> /\"\n",
    "echo \"================================================\"\n",
    "echo \"\"\n",
    "\n",
    "echo \"### /etc/systemd/system/multi-user.target.wants 配下にsshd.serviceのsymlink\"\n",
    "echo '$ ls -lh /etc/systemd/system/multi-user.target.wants/sshd.service | sed -e \"s/-> /\\n-> /\"'\n",
    "echo \"================================================\"\n",
    "ls -lh /etc/systemd/system/multi-user.target.wants/sshd.service | sed -e \"s/-> /\\n  -> /\"\n",
    "echo \"================================================\"\n",
    "echo \"\"\n",
    "\n",
    "echo \"### multi-user.targetは有効になっている\"\n",
    "echo '$ systemctl list-unit-files --no-pager | grep multi-user.target'\n",
    "echo \"================================================\"\n",
    "systemctl list-unit-files --no-pager | grep multi-user.target\n",
    "echo \"================================================\"\n",
    "echo \"※ つまり、CUIモードではsshd.serviceが起動する\"\n"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Unitファイル"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Unitファイル構成\n",
    "\n",
    "* Unitセクション\n",
    "    * ユニットファイルの共通的な設定\n",
    "        * Unitの依存関係/順序関係など\n",
    "        * Unitのタイプに依存しない設定項目\n",
    "    * Description\n",
    "        * ユニットの説明\n",
    "    * After/Before\n",
    "        * 指定したユニットの実行順番の依存関係を設定\n",
    "            * 「After=bar.service」\n",
    "                * そのサービスはbar.serviceの起動処理が終わるまで起動しない\n",
    "    * Requires/Wants\n",
    "        * <font color=\"red\">このUnitと同時に起動されるべきUnitを指定</font>\n",
    "            * どちらが先に起動するかは限定していない\n",
    "        * ユニットの依存関係の定義\n",
    "            * 「Wants=bar.service」\n",
    "                * bar.serviceの起動が失敗してもそのサービスを起動処理をする\n",
    "                    * bar.serviceが無くても起動するサービスであれば起動はする\n",
    "            * 「Requires=bar.service」\n",
    "                * bar.serviceの起動が失敗したらそのサービスは起動しない\n",
    "        * 設定以外の指定方法\n",
    "            1. /etc/systemd/systemに移動\n",
    "            1. 「<設定ファイル名>.reqruires」および「<設定ファイル名>.wants」というディレクトリを作成\n",
    "            1. その中に他のUnitの設定ファイルへのシンボリックリンクを作成する\n",
    "* Serviceセクション\n",
    "    * そのサービスを実行するための設定\n",
    "    * Type\n",
    "        * 「ExecStart」で指定したコマンドでサービスのプロセスを起動した際に、起動完了をどのように判定するかを指定\n",
    "            * simple\n",
    "                * コマンドを実行した時点で起動完了と判断する\n",
    "                    * フォアグラウンドで実行を継続する場合\n",
    "                * 指定が無い場合のデフォルト\n",
    "            * forking\n",
    "                * 実行したコマンドが終了した時点で起動完了と判断する\n",
    "                    * 子プロセスをフォークしてバックグラウンドにまわして、最初のコマンド自体は終了する場合\n",
    "            * oneshot\n",
    "                * 「ExecStart」で指定したコマンドを実行して、それが完了したタイミングで起動完了（かつサービス終了）と判断する\n",
    "                    * デーモン型のプロセスではなく、一度だけ指定のコマンドを実行する場合\n",
    "            * dbus\n",
    "                * フォアグラウンドで実行するタイプの中でもD-Busを利用するサービス\n",
    "                * 「BusName」にそのサービスのbus接続名を指定\n",
    "                    * systemdは、D-Bus上にこの接続名の接続が現れたタイミングでサービスが起動したものと判定\n",
    "    * ExecStart\n",
    "        * サービス起動コマンド\n",
    "    * ExecReload\n",
    "        * サービスリロードコマンド\n",
    "            * Apacheのgracefulはこれに割り当てられている\n",
    "    * ExecStop\n",
    "        * サービス停止コマンド\n",
    "    * ExecStartPre/ExecStartPost\n",
    "        * サービス起動前後の追加コマンド\n",
    "            * サービス起動判定には関連させたくないコマンドを記載\n",
    "    * ExecStopPost\n",
    "        * サービス停止後に実行するコマンド\n",
    "        * サービスが異常停止した際にも実行される\n",
    "    * EnvironmentFile\n",
    "        * 環境変数を読み込むファイル\n",
    "    * PIDFile\n",
    "        * fork型サービスのメインプロセスのPIDファイル\n",
    "            * フォークの形式によってどのプロセスがメインプロセスとなるかが変わる\n",
    "            * systemdはメインプロセスのPIDを自動判定することができない\n",
    "                * メインプロセスのPIDを記載したPIDファイルを生成する\n",
    "                * これを「PIDFile」に指定すると、systemdはこのファイルからPIDを認識できる\n",
    "    * BusName\n",
    "        * D-Bus型サービスのbus接続名\n",
    "    * Restart\n",
    "        * サービスプロセス停止時の再起動条件\n",
    "        * デフォルトは「no」\n",
    "    * PrivateTmp\n",
    "        * サービス専用の/tmpと/var/tmpを用意する\n",
    "* Installセクション\n",
    "    * ユニットファイルの共通的な設定\n",
    "        * 「systemctl enable/disable」コマンドの動作に影響する設定項目\n",
    "    * WantedBy\n",
    "        * enable時にこのUnitの.wantsディレクトリにリンクを作成する\n",
    "    * RequiredBy\n",
    "        * enable時にこのUnitの.requiredディレクトリにリンクを作成する\n",
    "    * Also\n",
    "        * enable/disable時に同時にenable/disableするUnit\n",
    "    * Alias\n",
    "        * enable時にこのUnitの別名を用意\n",
    "        \n",
    "### 特殊環境変数\n",
    "\n",
    "* `$MAINPID`\n",
    "    * systemdから実行したコマンドのPID\n",
    "        * メインプロセスのPIDとして認識される\n",
    "        * 「ExecReload」に対してメインプロセスにHUPシグナルを送るコマンドを記載する際になどに使用できる\n",
    "\n",
    "### D-Bus\n",
    "\n",
    "* D-Busとは\n",
    "    * systemdの環境で標準となるプロセス間通信用のメッセージバス機能\n",
    "    * 起動後に固有の「bus接続名」を指定して、D-Busに接続を行う"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### postfix\n",
    "\n",
    "```\n",
    "### /usr/lib/systemd/system/postfix.service\n",
    "================================================\n",
    "[Unit]\n",
    "Description=Postfix Mail Transport Agent\n",
    "After=syslog.target network.target\n",
    "Conflicts=sendmail.service exim.service\n",
    "\n",
    "[Service]\n",
    "Type=forking\n",
    "PIDFile=/var/spool/postfix/pid/master.pid\n",
    "EnvironmentFile=-/etc/sysconfig/network\n",
    "ExecStartPre=-/usr/libexec/postfix/aliasesdb\n",
    "ExecStartPre=-/usr/libexec/postfix/chroot-update\n",
    "ExecStart=/usr/sbin/postfix start\n",
    "ExecReload=/usr/sbin/postfix reload\n",
    "ExecStop=/usr/sbin/postfix stop\n",
    "\n",
    "[Install]\n",
    "WantedBy=multi-user.target\n",
    "================================================\n",
    "```\n",
    "\n",
    "* Unitセクション\n",
    "    * Conflicts\n",
    "        * Systemdはこの関係が定義されたプロセスは同時起動しない\n",
    "* Serviceセクション\n",
    "    * イコール「=」直後のハイフン「-」の意味\n",
    "        * EnvironmentFile\n",
    "            * ファイルが存在しなければ読み込まないだけで、エラーになったり警告を出したりもしない\n",
    "        * ExecStartPre\n",
    "            * コマンドが失敗してもエラーにならない\n",
    "* Installセクション\n",
    "    * WantedBy=multi-user.target\n",
    "        * 「multi-user.target.wants」ディレクトリ内にこの設定ファイルへのシンボリックリンクが作成される\n",
    "        * 一般的なサービスの場合\n",
    "            * multi-user.target（旧来のrunlevel 3に相当）、もしくはgraphical.target（runlevel 5に相当）"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### shirasagi-unicorn\n",
    "\n",
    "[shirasagi/bin/install.sh](https://github.com/shirasagi/shirasagi/blob/master/bin/install.sh#L303)\n",
    "\n",
    "```\n",
    "### /etc/systemd/system/shirasagi-unicorn.service\n",
    "================================================\n",
    "[Unit]\n",
    "Description=Shirasagi Unicorn Server\n",
    "After=mongod.service\n",
    "\n",
    "[Service]\n",
    "EnvironmentFile=-/etc/profile.d/rvm.sh\n",
    "User=shirasagi\n",
    "WorkingDirectory=/var/www/shirasagi\n",
    "ExecStart=/usr/local/rvm/rubies/default/bin/bundle exec rake unicorn:start\n",
    "ExecStop=/usr/local/rvm/rubies/default/bin/bundle exec rake unicorn:stop\n",
    "ExecReload=/usr/local/rvm/rubies/default/bin/bundle exec rake unicorn:restart\n",
    "Type=forking\n",
    "PIDFile=/var/www/shirasagi/tmp/pids/unicorn.pid\n",
    "\n",
    "[Install]\n",
    "WantedBy=multi-user.target\n",
    "================================================\n",
    "```\n",
    "\n",
    "* Serviceセクション\n",
    "    * User\n",
    "        * 実行ユーザを指定\n",
    "    * Group\n",
    "        * グループを指定 (このファイルには無いがグループを指定できる)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.1"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
